home *** CD-ROM | disk | FTP | other *** search
/ AGA Toolkit '97 / The AGA Toolkit '97.iso / programming / asm / popt / peephole.doc < prev    next >
Encoding:
Text File  |  1996-09-07  |  54.7 KB  |  1,234 lines

  1. THIS IS A DUMP FILE THAT LISTS PEEPHOLE OPTIMIZATIONS DONE BY POPT,
  2. (c) by Samuel DEVULDER, 1995.
  3.  
  4. UNSAFE optimizations are marked. Tell me if some marks are missing.
  5.  
  6. **** WHAT IS DONE IN peep1.c:
  7.  
  8.     +------------------------------------------------------------------
  9.     |      OP_ARITHM_UN() - is op a unary arithmetic operation
  10.     +------------------------------------------------------------------
  11.     |      clr.l  Dn               =>      moveq  #0,Dn
  12.     |
  13.     | For 68020/30 this does not improve speed but may help for
  14.     | further optimisations.
  15.     +------------------------------------------------------------------
  16.     |      move.x  #n,Dn           =>      moveq  #n,Dn
  17.     |
  18.     | Moveq is always a long operation, but as long as the
  19.     | immediate value is appropriate, we don't care what the
  20.     | original length was. Clearing upper bytes won't matter.
  21.     | This might cause a bug !
  22.     +------------------------------------------------------------------
  23.     |      move.x  #0,X            =>      clr.x   X
  24.     |
  25.     | X!=Rn.
  26.     +------------------------------------------------------------------
  27.     |      and.l #$ffffxxxx,Dx     =>      and.w #xxxx,Dx
  28.     +------------------------------------------------------------------
  29.     |      or.l #$0000xxxx,Dx      =>      or.w #xxxx,Dx
  30.     |
  31.     | OR or EOR.
  32.     +------------------------------------------------------------------
  33.     |      and.l #65535,Dx         =>      swap  dx
  34.     |                                      clr.w dx
  35.     |                                      swap  dx
  36.     | Not for 68020+.
  37.     +------------------------------------------------------------------
  38.     |      add.l #n,An             =>      add.w #n,An
  39.     |
  40.     | Where -32768<=n<=32767 and add or sub. Not for 68020+.
  41.     +------------------------------------------------------------------
  42.     |      add.x  #n, X            =>      addq.x  #n, X
  43.     |
  44.     | Where 1 <= n <= 8.
  45.     +------------------------------------------------------------------
  46.     |      add.x  #n, X            =>      subq.x  #-n, X
  47.     |
  48.     | Where -8 <= n <= -1.
  49.     +------------------------------------------------------------------
  50.     |      sub.x  #n, X            =>      subq.x  #n, X
  51.     |
  52.     | Where 1 <= n <= 8.
  53.     +------------------------------------------------------------------
  54.     |      sub.x  #n, X            =>      addq.x  #-n, X
  55.     |
  56.     | Where -8 <= n <= -1.
  57.     +------------------------------------------------------------------
  58.     |      movem.y X,Y             =>      <deleted>
  59.     |
  60.     | delete if mask is empty
  61.     +------------------------------------------------------------------
  62.     | Delete instruction that sets CC when CC is dead:
  63.     +------------------------------------------------------------------
  64.     |      CMP     X,Y             =>      <deleted>
  65.     |
  66.     | Delete if CC is dead and X or Y must not be INC or DEC. UNSAFE.
  67.     +------------------------------------------------------------------
  68.     |      TST     X               =>      <deleted>
  69.     |
  70.     | Delete if CC is dead and X must not be INC or DEC. UNSAFE.
  71.     +------------------------------------------------------------------
  72.     |      ARITHM  X,Rn            =>      <deleted>
  73.     |
  74.     | Remove instruction if Rn and CC are dead. This is most often
  75.     | used to eliminate the fixup of SP following a function call 
  76.     | when we're just about to return, since the "unlk" clobbers SP
  77.     | anyway. X must not be INC or DEC. ARITHM can also be a MOVE.
  78.     +------------------------------------------------------------------
  79.     |      ARITHM  Rn              =>      <deleted>
  80.     |
  81.     | Remove instruction if Rn and CC are dead.
  82.     +------------------------------------------------------------------
  83.     |      move.x  X,X             =>      tst.x   X
  84.     |
  85.     | If X isn't INC or DEC. (delete if X=An).
  86.     +------------------------------------------------------------------
  87.     |      add[ai].x  #n, Am       =>      lea  n(Am), Am
  88.     |
  89.     | Where 'n' is a valid displacement. UNSAFE since lea doesnt
  90.     | set the flags. Not for 68040.
  91.     +------------------------------------------------------------------
  92.     |      lea  n(Am),Am           =>      addq.w #n,Am    if n>0
  93.     |                                      subq.w #-n      if n<0
  94.     |
  95.     | Where -8<=n<=8. UNSAFE since addq sets flags.
  96.     +------------------------------------------------------------------
  97.     |      cmp.x   #0, X           =>      tst.x   X
  98.     |
  99.     | Where X is not An.
  100.     +------------------------------------------------------------------
  101.     |      cmp.l   #0,An           =>      move.l  An,Ds
  102.     |
  103.     | Where Ds is dead.
  104.     +------------------------------------------------------------------
  105.     |      cmp.l   #0,An           =>      cmp.w   #0,An
  106.     +------------------------------------------------------------------
  107.     |      cmp.x   #y, Rm          =>      subq.x  #abs(y),Rm   (y>0)
  108.     |                                      addq                 (y<0)
  109.     |
  110.     | Where Rm is dead and (1 <= abs(y) <= 8).
  111.     +------------------------------------------------------------------
  112.     |      lsl.x   #1,Dx           =>      add.x   Dx,Dx
  113.     |      asl.x
  114.     +------------------------------------------------------------------
  115.     |      move.l  An,-(SP)        =>      pea     (An)
  116.     |
  117.     | For further optimizations with INDEX mode. Will be set back
  118.     | to original code if useless.
  119.     +------------------------------------------------------------------
  120.     |      lea     (An),Am         =>      move.l  An,Am
  121.     +------------------------------------------------------------------
  122.     |      INST.x  #n,X            =>      moveq   #n,Ds
  123.     |                                      INST.x  Ds,X
  124.     |
  125.     | Where Ds is a scratch reg, INST=ADD | ADDA | ADDI | AND | ANDI |
  126.     | OR | ORI | EOR | EORI | CMP | CMPA | SUB | SUBI | SUBA | MOVE |
  127.     | MOVEA. Not for 68040.
  128.     +------------------------------------------------------------------
  129.  
  130. **** WHAT IS DONE IN peep2.c:
  131.  
  132.     +------------------------------------------------------------------
  133.     |      move.l  #0,Dx           =>      <deleted>
  134.     |      move.x  Dx,X                    clr.x   X
  135.     |
  136.     | Where Dx is dead. X!=Rn
  137.     +------------------------------------------------------------------
  138.     | Avoid "tst" instructions following instructions that
  139.     | set the Z flag.
  140.     +------------------------------------------------------------------
  141.     |      move.x  X,Y             =>      move.x  X,Y
  142.     |      tst.x   X or Y                  <deleted>
  143.     |
  144.     | Where Y is not An, because "movea" doesn't set the
  145.     | zero flag.
  146.     +------------------------------------------------------------------
  147.     |      ARITHM.x X,Y            =>      ARITHM.x X,Y
  148.     |      tst.x    Y                      <deleted>
  149.     |
  150.     | Where Y is not An, because "adda" doesn't set the
  151.     | zero flag.
  152.     +------------------------------------------------------------------
  153.     |      ext.x   Dn              =>      ext.x   Dn
  154.     |      tst.x   Dn                      <deleted>
  155.     +------------------------------------------------------------------
  156.     |      move.x  X,Dn            =>      move.x  X,Dn
  157.     |      ext.x   Dn                      <deleted>
  158.     |      b<cc>                           b<cc>
  159.     |
  160.     |  Where Dn is dead after the "ext".
  161.     +------------------------------------------------------------------
  162.     |      ext.x   Dm              =>      <deleted>
  163.     |      tst.x   Dm                      tst.y   Dm
  164.     |
  165.     | Where Dm is dead after the "tst". y = w if x = l
  166.     |                                   y = b if x = w
  167.     +------------------------------------------------------------------
  168.     |      ext.l   Dm              =>      <deleted>
  169.     |      INST    ..N(An,Dm.l)..          INST    ..N(An,Dm.w)..
  170.     |
  171.     | Where Dm is dead.
  172.     +------------------------------------------------------------------
  173.     | Avoid intermediate registers.
  174.     +------------------------------------------------------------------
  175.     |      move.x  X,Dm            =>      INST.x  X,Dn
  176.     |      INST.x  Dm,Dn                   <deleted>
  177.     |
  178.     | Where Dm is dead, and INST is one of: add, sub, and, or, cmp.
  179.     +------------------------------------------------------------------
  180.     | Avoid silly moves
  181.     +------------------------------------------------------------------
  182.     |      move.x  X,Y             =>      move.x  X,Y
  183.     |      move.x  Y,X                     <deleted>
  184.     |
  185.     | Y can't be an A reg.
  186.     +------------------------------------------------------------------
  187.     |      move.x  X,Y             =>      move.x  X,Rn
  188.     |      move.x  Y,Rn                    move.x  Rn,Y
  189.     |
  190.     | Where Y isn't INC or DEC, and isn't register direct
  191.     | and Y doesn't depend on Rn.
  192.     +------------------------------------------------------------------
  193.     |      move.l  Dm,An           =>      move.l  Dm,Ao
  194.     |      lea     (An),Ao                 <deleted>
  195.     |
  196.     | Where An is dead.
  197.     +------------------------------------------------------------------
  198.     |      lea     X,An            =>      lea     X,Ao
  199.     |      lea     (An),Ao                 <deleted>
  200.     |
  201.     | Where An is dead.
  202.     +------------------------------------------------------------------
  203.     |      lea     N(Am), Am       =>      <deleted>
  204.     |      INST    (Am)[,...]              INST    N(Am)[,...]
  205.     |
  206.     | Where Am is either dead after the second instruction or
  207.     | is a direct destination of the second instruction.
  208.     +------------------------------------------------------------------
  209.     |      move.l  Am,An           =>      <deleted>
  210.     |      lea     [x](An[,Rx.y]),Ap       lea     [x](Am[,Rx.y]),Ap
  211.     |
  212.     | Where An is either dead after the second instruction or
  213.     | is a direct destination of the second instruction.
  214.     +------------------------------------------------------------------
  215.     |      move.l  Am,An           =>      <deleted>
  216.     |      INST    [N](An[,Rx.y]),X        INST    [N](Am[,Rx.y]),X
  217.     |
  218.     | Where An is dead. 
  219.     +------------------------------------------------------------------
  220.     |                                        __
  221.     |      s<cc>   Dn              =>      s<cc>   Dn
  222.     |      not.b   Dn                      <deleted>
  223.     +------------------------------------------------------------------
  224.     |      move.x  #0,Rn           =>      <deleted>
  225.     |      cmp.x   Rn,X                    tst.x   X
  226.     |
  227.     | Where Rn is dead.
  228.     +------------------------------------------------------------------
  229.     |      move.x  #y,Rn           =>      <deleted>
  230.     |      cmp.x   Rn,Rm                   subq.x  #abs(y),Rm  (y>0)
  231.     |                                      addq                (y<0)
  232.     |
  233.     | Where Rm and Rn are dead and (1 <= abs(y) <= 8).
  234.     +------------------------------------------------------------------
  235.  
  236. **** WHAT IS DONE IN peep2_2.c:
  237.  
  238.     +------------------------------------------------------------------
  239.     |      lea     N(Am),Am        =>      <deleted>
  240.     |      INST    X,(Am)                  INST    X,N(Am)
  241.     |
  242.     | Where X doesn't reference Am, and Am is dead after the
  243.     | second instruction.
  244.     +------------------------------------------------------------------
  245.     |      lea     X,Am            =>      <deleted>
  246.     |      clr.x   (Am)                    clr.x   X
  247.     |
  248.     | Where Am is dead.
  249.     +------------------------------------------------------------------
  250.     |      lea     X,Am            =>      <deleted>
  251.     |      move.x  Y,(Am)                  move.x  Y,X
  252.     |
  253.     | Where Am is dead.
  254.     +------------------------------------------------------------------
  255.     |      lea     X,Am            =>      <deleted>
  256.     |      move.x  (Am), Y                 move.x  X,Y
  257.     |
  258.     | Where Am is dead.
  259.     +------------------------------------------------------------------
  260.     |      move.x  Dm,X            =>      move.x  Dm,X
  261.     |      cmp.x   #N,X                    cmp.x   #N,Dm
  262.     |
  263.     | Where X isn't register direct.
  264.     |
  265.     | Since X generally references memory, we can compare
  266.     | with the register faster.
  267.     +------------------------------------------------------------------
  268.     |      move.x  X,Dm            =>      move.x  X,Dm
  269.     |      cmp.x   #N,X                    cmp.x   #N,Dm
  270.     |
  271.     | Where X isn't register direct.
  272.     |
  273.     | Since X generally references memory, we can compare
  274.     | with the register faster.
  275.     +------------------------------------------------------------------
  276.     | Try to use register indirect w/ displacement and/or index
  277.     +------------------------------------------------------------------
  278.     |      add.l   Am,Rn           =>      <deleted>
  279.     |      move.l  Rn,Ao                   lea     0(Am,Rn.l),Ao
  280.     |
  281.     | Where Rn is dead. UNSAFE since the first add sets the flags
  282.     | (if Rn=Dn). Not for 68020/30/40.
  283.     +------------------------------------------------------------------
  284.     |      add.lw  Rm,An           =>      <deleted>
  285.     |      ...(1)                          ...(1)
  286.     |      INST.x  ..[N](An)..             INST.x  ..[N](An,Rm.lw)..
  287.     |
  288.     | Where An is dead and not used in (1) and Rm not set in (1). 
  289.     | Not for 68040. (not for 68020/30 if N=0).
  290.     +------------------------------------------------------------------
  291.     |      lea     N(Am),An        =>      lea     N(Am,Ro.l),An
  292.     |      add.l   Ro,An                   <deleted>
  293.     |
  294.     | Not for 68040. (For 68020/30 we gain 2 instructions bytes).
  295.     +------------------------------------------------------------------
  296.     |      lea     X,Ax            =>      lea     X,Ay
  297.     |      move.l  Ax,Ay                   <deleted>
  298.     |
  299.     | Where Ax is dead.
  300.     +------------------------------------------------------------------
  301.     |      move.x  An,Am           =>      <deleted>
  302.     |      cmp.x   X,Am                    cmp.x   X,An
  303.     |
  304.     | Where Am is dead and X does not set An.
  305.     +------------------------------------------------------------------
  306.     |      move.y  Ry,Rx           =>      <deleted>
  307.     |      ...(1)                          ...(1)
  308.     |      INST.x  ..N(An,Rx.y)..          INST.x  ..N(An,Ry.y)..
  309.     |
  310.     | Where Rx is dead and not used in (1) and Ry not set in (1). 
  311.     +------------------------------------------------------------------
  312.     |      move.l  An,Am           =>      <deleted>
  313.     |      ...(1)                          ...(1)
  314.     |      INST.x  ..N(Am[,Rx.y])..        INST.x  ..N(An[,Rx.y])..
  315.     |
  316.     | Where Am is dead and not used in (1) and An not set in (1). 
  317.     +------------------------------------------------------------------
  318.     |      addq    #N,sp           =>      addq    #N-4,sp 
  319.     |      ....                            ....
  320.     |      <stuff that  >                  <stuff that  >
  321.     |      <doesn't use >                  <doesn't use >
  322.     |      <SP ...      >                  <SP ...      >
  323.     |      ....                            ....
  324.     |      INST.l  ..-(sp)..       =>      INST.l  ..(sp)..
  325.     |      
  326.     | addq or lea N(SP),SP. addq is deleted if N==4.
  327.     +------------------------------------------------------------------
  328.     |      addq    #N,sp           =>      addq    #N-2,sp
  329.     |      ....                            ....
  330.     |      <stuff that  >                  <stuff that  >
  331.     |      <doesn't use >                  <doesn't use >
  332.     |      <SP ...      >                  <SP ...      >
  333.     |      ....                            ....
  334.     |      INST.w  ..-(sp)..       =>      INST.w  ..(sp)..
  335.     |
  336.     | addq or lea N(SP),SP. addq is deleted if N==2.
  337.     +------------------------------------------------------------------
  338.  
  339. **** WHAT IS DONE IN peep2_3.c:
  340.  
  341.     +------------------------------------------------------------------
  342.     |      lea    N(An),Am         =>      <deleted>
  343.     |      ...(1)                          ...(1)
  344.     |      INST.x ..[M](Am[,Rx.y])..       INST.x ..[N+]M(An[,Rx.y])..
  345.     |
  346.     | Where Am is dead and not used in (1) and An not set in (1). 
  347.     | If Rx==Am then use 2*N instead of N.
  348.     +------------------------------------------------------------------
  349.     |      lea     N(An,Rx.y),Am   =>      <deleted>
  350.     |      ...(1)                          ...(1)
  351.     |      INST.x  ..[M](Am)..             INST.x  ..N[+M](An,Rx.y)..
  352.     |
  353.     | Where Am is dead and not used in (1) and (An,Dx) are not set 
  354.     | in (1). 
  355.     +------------------------------------------------------------------
  356.     |      move.?  #n,Rn           =>      move.?  #n,Rn
  357.     |      ....                            ....
  358.     |      <stuff>                         <stuff>
  359.     |      ....                            ....
  360.     |      move.?  #n,Rn           =>      <deleted>
  361.     |
  362.     | Where <stuff> doesn't set Rn. Also make sure that
  363.     | the second move isn't followed by a conditional branch.
  364.     | In that case leave everything alone since the branch
  365.     | probably relies on flags set by the move.
  366.     | UNSAFE since last instruction deleted and may set flags.
  367.     +------------------------------------------------------------------
  368.     |      move.?  Rm,Rn           =>      move.?  Rm,Rn
  369.     |      ....                            ....
  370.     |      <stuff>                         <stuff>
  371.     |      ....                            ....
  372.     |      move.?  Rm,Rn           =>      <deleted>
  373.     |
  374.     | Where <stuff> doesn't set Rm or Rn. Also make sure that
  375.     | the second move isn't followed by a conditional branch.
  376.     | In that case leave everything alone since the branch
  377.     | probably relies on flags set by the move.
  378.     | UNSAFE since last instruction deleted and may set flags.
  379.     +------------------------------------------------------------------
  380.     |      move.l  Am,Dn           =>      move.l  Am,Ao
  381.     |      ....                            ....
  382.     |      <stuff>                         <stuff>
  383.     |      ....                            ....
  384.     |      move.l  Dn,Ao           =>      <deleted>
  385.     |
  386.     | Where "stuff" doesn't set Dn. 
  387.     | UNSAFE since the first move may sets the flags.
  388.     +------------------------------------------------------------------
  389.     | Try to use the pre-decrement an post modes whenever possible.
  390.     +------------------------------------------------------------------
  391.     |      sub[q].lw #1,Am         =>      <deleted>
  392.     |      ....                            ....
  393.     |      <stuff>                         <stuff>
  394.     |      ....                            ....
  395.     |      INST.b  ..(Am)..        =>      INST.b  ..-(Am)..
  396.     |
  397.     | Nothing in "stuff" can refer to Am.
  398.     +------------------------------------------------------------------
  399.     |      sub[q].lw #2,Am         =>      <deleted>
  400.     |      ....                            ....
  401.     |      <stuff>                         <stuff>
  402.     |      ....                            ....
  403.     |      INST.w  ..(Am)..        =>      INST.w  ..-(Am)..
  404.     |
  405.     | Nothing in "stuff" can refer to Am.
  406.     +------------------------------------------------------------------
  407.     |      sub[q].lw #4,Am         =>      <deleted>
  408.     |      ....                            ....
  409.     |      <stuff>                         <stuff>
  410.     |      ....                            ....
  411.     |      INST.l  ..(Am)..        =>      INST.l  ..-(Am)..
  412.     |
  413.     | Nothing in "stuff" can refer to Am.
  414.     +------------------------------------------------------------------
  415.  
  416. **** WHAT IS DONE IN peep2_4.c:
  417.  
  418.     +------------------------------------------------------------------
  419.     |      INST.b  ..(Am)..        =>      INST.b  ..(Am)+..
  420.     |      ....                            ....
  421.     |      <stuff>                         <stuff>
  422.     |      ....                            ....
  423.     |      add[q].lw #1,Am         =>      <deleted>
  424.     |
  425.     | Nothing in "stuff" can refer to Am.
  426.     | Note: we go upward..
  427.     +------------------------------------------------------------------
  428.     |      INST.w  ..(Am)..        =>      INST.w  ..(Am)+..
  429.     |      ....                            ....
  430.     |      <stuff>                         <stuff>
  431.     |      ....                            ....
  432.     |      add[q].lw #2,Am         =>      <deleted>
  433.     |
  434.     | Nothing in "stuff" can refer to Am.
  435.     | NOTE: we go upward...
  436.     +------------------------------------------------------------------
  437.     |      INST.l  ..(Am)..        =>      INST.l  ..(Am)+..
  438.     |      ....                            ....
  439.     |      <stuff>                         <stuff>
  440.     |      ....                            ....
  441.     |      add[q].lw #4,Am         =>      <deleted>
  442.     |
  443.     | Nothing in "stuff" can refer to Am.
  444.     | NOTE: we go upward...
  445.     +------------------------------------------------------------------
  446.     | avoid too many reg moves..
  447.     +------------------------------------------------------------------
  448.     |      move[q].x X,Ax          =>      move[q].x X,Ay
  449.     |      ....                            ....
  450.     |      <stuff1>                        <stuff2>
  451.     |      ....                            ....
  452.     |      move.x    Ax,Ay         =>      <deleted>
  453.     |
  454.     | stuff2 is stuff1 where Ax is replaced by Ay...
  455.     | Where Ax is dead and stuff does not ref nor set Ay and
  456.     | uses Ax with .x and contains no branch to subroutine.
  457.     +------------------------------------------------------------------
  458.     |      move[q].x X,Dx          =>      move[q].x X,Dy
  459.     |      ....                            ....
  460.     |      <stuff1>                        <stuff2>
  461.     |      ....                            ....
  462.     |      move.x    Dx,Dy         =>      <deleted>
  463.     |
  464.     | stuff2 is stuff1 where Dx is replaced by Dy...
  465.     | Where Dx is dead and stuff does not ref nor set Dy and
  466.     | uses Dx with .x (or < .x) and contains no branch to 
  467.     | subroutine.
  468.     | UNSAFE since the last move may set the flags and is deleted.
  469.     +------------------------------------------------------------------
  470.     |      sub.w   #1,Dx           =>      db<cc>  Dx,lbl
  471.     |      b<cc>   lbl                     b<cc>   lbl
  472.     +------------------------------------------------------------------
  473.     |      move.x  #n,Dx           =>      move.x  #n-1,Dx 
  474.     |      ...(1)                          ...(1)
  475.     |      bra     lbl1                    bra     lbl2
  476.     |      ...(2)                          ...(2)
  477.     | lbl1 dbf     Dx,lbl2           lbl1  dbf     Dx,lbl2
  478.     |      ...(3)                    lbl3  ...(3)
  479.     |
  480.     | Where Dx is not used in (1). If n==0 use (bra lbl3) else 
  481.     | use (bra lbl2).
  482.     +------------------------------------------------------------------
  483.  
  484. **** WHAT IS DONE IN peep2_5.c:
  485.  
  486.     +------------------------------------------------------------------
  487.     |      move.x  X,Dx            =>      moveq   #0,Dx
  488.     |      and.l   #65535,Dx               move.y  X,Dx
  489.     |
  490.     | Where X is REG or IMM. If x=.l then y=.w else y=x.
  491.     +------------------------------------------------------------------
  492.     |      and.l   #65535,Dx       =>      moveq   #0,Dy
  493.     |      move.l  Dx,Dy                   move.w  Dx,Dy
  494.     |
  495.     | Where Dx is dead.
  496.     +------------------------------------------------------------------
  497.     |      ext.l   Dx              =>      <deleted>
  498.     |      move.w  Dx,X                    move.w  Dx,X
  499.     |
  500.     | Where Dx is dead.
  501.     +------------------------------------------------------------------
  502.     |      move.l  Dx,Dy           =>      <deleted>
  503.     |      ....                            ....
  504.     |      <stuff1>                        <stuff2>
  505.     |      ....                            ....
  506.     |      <inst that sets Dx>(2)          <inst that sets Dx>
  507.     |
  508.     | Where Dx is dead, Dy is dead at (2). <stuff2> is <stuff1> 
  509.     | where Dy is replaced by Dx. UNSAFE: the deleted move may
  510.     | set flags. Note (2) may also be a breakflow instruction.
  511.     +------------------------------------------------------------------
  512.     |      move.z  Ry,Rx           =>      <deleted>
  513.     |      ...(1)                          ...(1)
  514.     |      INST.x ..M(Am,Rx.y)..           INST.x ..M(An,Ry.y)..
  515.     |
  516.     | Where Rx is dead and not used in (1) and Ry not set in (1). 
  517.     | Note, z must be greater than y.
  518.     +------------------------------------------------------------------
  519.     |      sub[q].z #N,Rx          =>      <deleted>
  520.     |      ...(1)                          ...(1)
  521.     |      INST    ..[M](Am,Rx.y)..        INST    ..[M]-N(Am,Rx.y)..
  522.     |
  523.     | Where Rx is dead and not used in (1). If Rx==Dx then .z 
  524.     | must be .l. Note: if Rx uses a multiplier then multiply N too.
  525.     +------------------------------------------------------------------
  526.     |      add[q].z #N,Rx          =>      <deleted>
  527.     |      ...(1)                          ...(1)
  528.     |      INST    ..[M](Am,Rx.y)..        INST    ..[M+]N(Am,Rx.y)..
  529.     |
  530.     | Where Rx is dead and not used in (1). If Rx==Dx then .z 
  531.     | must be .l. Note: if Rx uses a multiplier then multiply N too.
  532.     +------------------------------------------------------------------
  533.     |      move.x  Rm,X            =>      move.x  Rm,X
  534.     |      ...(1)                          ...
  535.     |      INST.x  X,Y                     INST.x  Rm,Y
  536.     |
  537.     | Where 'x' is the same, and 'X' has no side-effects and 
  538.     | is not register, Rm is not used in (1). INST!=lea
  539.     +------------------------------------------------------------------
  540.     |      move.x  X,Rm            =>      move.x  X,Rm
  541.     |      ...(1)                          ...
  542.     |      INST.x  X,Y                     INST.x  Rm,Y
  543.     |
  544.     | Where 'x' is the same, and 'X' has no side-effects and 
  545.     | is not register, Rm is not used in (1).
  546.     +------------------------------------------------------------------
  547.  
  548. **** WHAT IS DONE IN peep3.c:
  549.  
  550.     +------------------------------------------------------------------
  551.     |      move.l  Am,Rn           =>      lea     N(Am),Ao
  552.     |      add.l   #N,Rn                   <deleted>
  553.     |      move.l  Rn,Ao                   <deleted>
  554.     |
  555.     | Also, Rn must be dead after the third instruction.
  556.     | UNSAFE since the add sets the flags and move don't so check 
  557.     | if the 4th inst set them.
  558.     +------------------------------------------------------------------
  559.     |      move.l  Rm,Rn           =>      move.l  Rm,Ao
  560.     |      add.l   #N,Rn                   lea     N(Ao),Ao
  561.     |      move.l  Rn,Ao                   <deleted>
  562.     |
  563.     | Also, Rn must be dead after the third instruction.
  564.     | UNSAFE since the add sets the flags (if Rn==Dn) and move don't 
  565.     | so we check if the 4th inst set them. 
  566.     +------------------------------------------------------------------
  567.     |      move.l  Am,Rn           =>      lea     -N(Am),Ao
  568.     |      sub.l   #N,Rn                   <deleted>
  569.     |      move.l  Rn,Ao                   <deleted>
  570.     |
  571.     | Also, Rn must be dead after the third instruction.
  572.     | UNSAFE since the add sets the flags and move don't so check 
  573.     | if the 4th inst set them.
  574.     +------------------------------------------------------------------
  575.     |      move.l  Am,Rn           =>      lea     0(Am,Ro),Ap
  576.     |      add.x   Ro,Rn                   <deleted>
  577.     |      move.l  Rn,Ap                   <deleted>
  578.     |
  579.     | The second instruction can be either a word or long add.
  580.     | Also, Rn must be dead after the third instruction.
  581.     | UNSAFE since the add sets the flags (if Rn==Dn) and move 
  582.     | don't so check if the 4th inst set them. Not for 68040.
  583.     +------------------------------------------------------------------
  584.     |      move.l  X(Am),Rn        =>      move.l  X(Am),Ao
  585.     |      add.l   #N,Rn                   <deleted>
  586.     |      move.l  Rn,Ao                   lea     N(Ao),Ao
  587.     |
  588.     | Also, Rn must be dead after the third instruction.
  589.     | UNSAFE since the add sets the flags and move don't so check 
  590.     | if the 4th inst set them.
  591.     +------------------------------------------------------------------
  592.     |      move.x  X,Dn            =>      move.x  X,Do
  593.     |      ext.y   Dn                      ext.y   Do
  594.     |      move.y  Dn,Do           =>      <deleted>
  595.     |
  596.     | Where Dn is dead.
  597.     +------------------------------------------------------------------
  598.     |      move.l  X,Dm            =>      move.l  X,An
  599.     |      INST                            INST
  600.     |      move.l  Dm,An           =>      <deleted>
  601.     |
  602.     | Where INST doesn't modify Dm, and Dm is dead after i3
  603.     | UNSAFE since the last move doesn't change the flags.
  604.     +------------------------------------------------------------------
  605.  
  606. **** WHAT IS DONE IN peep3bis.c:
  607.  
  608.     +------------------------------------------------------------------
  609.     | Optimize code generated by *ptr++ in C..
  610.     +------------------------------------------------------------------
  611.     |      move.l  Am,An           =>      <deleted>
  612.     |      addq.lw #1,Am                   <deleted>
  613.     |      ....                            ....
  614.     |      <stuff>                         <stuff>
  615.     |      ....                            ....
  616.     |      INST.b  ..(An)..        =>      INST.b  ..(Am)+..
  617.     |
  618.     | An must be dead after the last instruction. Nothing in
  619.     | "stuff" can modify Am.
  620.     +------------------------------------------------------------------
  621.     |      move.l  Am,An           =>      <deleted>
  622.     |      addq.lw #2,Am                   <deleted>
  623.     |      ....                            ....
  624.     |      <stuff>                         <stuff>
  625.     |      ....                            ....
  626.     |      INST.w  ..(An)..        =>      INST.w  ..(Am)+..
  627.     |
  628.     | An must be dead after the last instruction. Nothing in
  629.     | "stuff" can modify Am.
  630.     +------------------------------------------------------------------
  631.     |      move.l  Am,An           =>      <deleted>
  632.     |      addq.lw #4,Am                   <deleted>
  633.     |      ....                            ....
  634.     |      <stuff>                         <stuff>
  635.     |      ....                            ....
  636.     |      INST.l  ..(An)..        =>      INST.l  ..(Am)+..
  637.     |
  638.     | An must be dead after the last instruction. Nothing in
  639.     | "stuff" can modify Am.
  640.     +------------------------------------------------------------------
  641.     |      move.l  Ax,Dy           =>      add.l   Ax,Ax
  642.     |      lsl.l   #2,Dy                   add.l   Ax,Ax
  643.     |      move.l  Dy,Ax
  644.     |
  645.     | Where Dy is dead. UNSAFE: lsl sets the flags. add does'nt.
  646.     +------------------------------------------------------------------
  647.     |      move.x  X,Rm            =>      <deleted>
  648.     |      INST2.x Do,Rm                   INST2.x X,Do
  649.     |      INST3.x Rm,Y                    INST3.x Do,Y
  650.     |
  651.     | Where Rm!=Do and (Rm,Do) are dead and INST2=ADD | OR | AND |
  652.     | EOR.
  653.     | UNSAFE: Do may set flags in INST2 that may be untouched by
  654.     | INST3.
  655.     +------------------------------------------------------------------
  656.     |      move.x  #0,Rn           =>      <deleted>
  657.     |      cmp.x   X,Rn                    tst.x   X
  658.     |      b<cc>   lbl                     b<cci>  lbl
  659.     |
  660.     | Where Rn is dead. b<cci> is the inverse cond. branch.
  661.     +------------------------------------------------------------------
  662.     |      move.x  #y,Rn           =>      <deleted>
  663.     |      cmp.x   Rm,Rn                   subq.x  #abs(y),Rm  (y>0)
  664.     |                                      addq                (y<0)
  665.     |      b<cc>   lbl                     b<cci>  lbl
  666.     |
  667.     | Where Rm and Rn are dead and (1 <= abs(y) <= 8). b<cci> is the 
  668.     | inverse cond. branch.
  669.     +------------------------------------------------------------------
  670.     |      move.y #I1,Rn           =>      <deleted>
  671.     |      add.x  Rn,Rm                    add.x #I1+I2,Rm
  672.     |      ...                             ...
  673.     |      <stuff that does not use Rm>    <stuff>
  674.     |      ...                             ...
  675.     |      add.x  #I2,Rm                   <deleted>
  676.     |      
  677.     | Add or sub.. Where Rn is dead and y>x. UNSAFE since the 2nd 
  678.     | add set the flags so test if inst after last add set flags.
  679.     +------------------------------------------------------------------
  680.  
  681. **** WHAT IS DONE IN peep4.c:
  682.  
  683.     +------------------------------------------------------------------
  684.     |      move.x  X,Dx            =>      moveq   #0,Dx
  685.     |      swap    Dx                      move.y  X,Dx
  686.     |      clr.w   Dx                      <deleted>
  687.     |      swap    Dx                      <deleted>
  688.     |
  689.     | Where X is REG or IMM. If x=.l then y=.w else y=x
  690.     +------------------------------------------------------------------
  691.     |      swap    Dx              =>      moveq   #0,Dy
  692.     |      clr.w   Dx                      move.w  Dx,Dy
  693.     |      swap    Dx                      <deleted>
  694.     |      move.l  Dx,Dy                   <deleted>
  695.     |
  696.     | Where Dx is dead.
  697.     +------------------------------------------------------------------
  698.     |      move.w  Dm, Dn          =>      dbf     Dm,lbl
  699.     |      sub.w   #1,Dm                   <deleted>
  700.     |      tst.w   Dn                      <deleted>
  701.     |      bne     lbl                     <deleted>
  702.     |
  703.     | Where Dn is dead after the test.
  704.     +------------------------------------------------------------------
  705.     |      move.l  Dm,Dn           =>              dbf     Dm,lbl
  706.     |      sub.l   #1,Dm                           clr.w   Dm
  707.     |      tst.l   Dn                              subq.l  #1,Dm
  708.     |      bne     lbl                             bcc     lbl
  709.     |      ...                                     ...
  710.     |
  711.     | Where Dn is dead after the test.
  712.     | This is faster since the inner loop is faster (if dm!=0).
  713.     +------------------------------------------------------------------
  714.  
  715. **** WHAT IS DONE IN asp68k.c:
  716.  
  717.     +------------------------------------------------------------------
  718.     |      INST 0(An),X            =>      INST (An),X
  719.     +------------------------------------------------------------------
  720.     |      INST X,0(An)            =>      INST X,(An)
  721.     +------------------------------------------------------------------
  722.     |      add*.x #0,Dx            =>      tst.x Dx
  723.     +------------------------------------------------------------------
  724.     |      add.x #I1,Rm            =>      add.x #I1+I2,Rm
  725.     |      ...                             ...
  726.     |      <stuff that does not use Rm>    <stuff>
  727.     |      ...                             ...
  728.     |      add.x #I2,Rm                    <deleted>
  729.     |
  730.     | Add or sub.. UNSAFE since the 2nd add set the flags so test
  731.     | if inst after last add set flags.
  732.     +------------------------------------------------------------------
  733.     |      addq.x #4,sp            =>      move.l ax,(sp)
  734.     |      pea (ax)                        <deleted>
  735.     |
  736.     | Where x = w or l
  737.     +------------------------------------------------------------------
  738.     |      and.l #n,dx             =>      bclr.l #b,dx
  739.     |
  740.     | Where not(n) = 2^b (only 1 bit off). Not for 68020+.
  741.     +------------------------------------------------------------------
  742.     |      asl.b #n,dx             =>      clr.b dx
  743.     |
  744.     | For asr or lsl or lsr also. Where n>=8. UNSAFE: status flags are
  745.     | wrong so test if next instruction sets them.
  746.     +------------------------------------------------------------------
  747.     |      asl.l #16,dx            =>      swap  dx
  748.     |                                      clr.w dx
  749.     |
  750.     | For lsl also. UNSAFE: status flags are wrong so test if next
  751.     | instruction sets them. Not for 68020/30.
  752.     +------------------------------------------------------------------
  753.     |      asr.l #16,dx            =>      clr.w dx
  754.     |                                      swap  dx
  755.     |
  756.     | For lsr also. UNSAFE: status flags are wrong so test if next
  757.     | instruction sets them. Not for 68020/30.
  758.     +------------------------------------------------------------------
  759.     |      asl.l #n,dx             =>      asl.w #(n-16),dx
  760.     |                                      swap dx
  761.     |                                      clr.w dx
  762.     |
  763.     | Where asl or lsl and 16<n<32. UNSAFE: status flags are wrong
  764.     | so test if next instruction sets them. Not for 68020+.
  765.     +------------------------------------------------------------------
  766.     |      asl.l #n,dx             =>      moveq #0,dx
  767.     |
  768.     | Where asl or lsl or asr or lsr and 32<=n. UNSAFE: status flags
  769.     | are wrong so test if next instruction sets them.
  770.     +------------------------------------------------------------------
  771.     |      asl.w #n,dx             =>      clr.w dx
  772.     |
  773.     | Where asl or lsl or asr or lsr and 16<=n. UNSAFE: status flags
  774.     | are wrong so test if next instruction sets them.
  775.     +------------------------------------------------------------------
  776.     |      asr.l #n,dx             =>      swap  dx
  777.     |                                      asr.w #(n-16),dx
  778.     |                                      clr.w dx
  779.     |
  780.     | Where asl or lsl and 16<n<32. UNSAFE: status flags are wrong
  781.     | so test if next instruction sets them. Not for 68020+.
  782.     +------------------------------------------------------------------
  783.     |      bclr.l #n,dx            =>      and.w #m,dx
  784.     |
  785.     | Where 0 <= n <= 15, m = 65535-(2^n). UNSAFE: status flags
  786.     | are wrong so test if next instruction sets them.
  787.     +------------------------------------------------------------------
  788.     |      bset.l #n,dx            =>      or.w #m,dx
  789.     |
  790.     | Where 0 <= n <= 15, m = (2^n). UNSAFE: status flags are wrong
  791.     | so test if next instruction sets them.
  792.     +------------------------------------------------------------------
  793.     |      btst.l    #7,dx         =>      tst.b     dx
  794.     |      beq | bne ??                    bpl | bmi ??
  795.     |
  796.     | UNSAFE: btst just sets Z while tst sets N also. So test if
  797.     | next instruction sets the flags.
  798.     +------------------------------------------------------------------
  799.     |      btst.l    #15,dx        =>      tst.w     dx
  800.     |      beq | bne ??                    bpl | bmi ??
  801.     |
  802.     | UNSAFE: btst just sets Z while tst sets N also. So test if
  803.     | next instruction sets the flags.
  804.     +------------------------------------------------------------------
  805.     |      btst.l    #31,dx        =>      tst.l     dx
  806.     |      beq | bne ??                    bpl | bmi ??
  807.     |
  808.     | UNSAFE: btst just sets Z while tst sets N also. So test if
  809.     | next instruction sets the flags.
  810.     +------------------------------------------------------------------
  811.     |      No div optimisation because of the remainder..
  812.     +------------------------------------------------------------------
  813.  
  814. **** WHAT IS DONE IN asp68kbis.c:
  815.  
  816.     +------------------------------------------------------------------
  817.     |      eor.x #-1,*             =>      not.x *
  818.     +------------------------------------------------------------------
  819.     |      lea (Am),Am             =>      <deleted>
  820.     +------------------------------------------------------------------
  821.     |      move optim
  822.     +------------------------------------------------------------------
  823.     |      move.b  #-1,X           =>      st      X
  824.     |
  825.     | UNSAFE: status flags are wrong so test if next instruction
  826.     | sets them. Not for 68040.
  827.     +------------------------------------------------------------------
  828.     |      move.l  #n,-(sp)        =>      pea     n.W
  829.     |
  830.     | Where n is a valid displacement. Not for 68040.
  831.     +------------------------------------------------------------------
  832.     |      move.l  #n,Dx           =>      moveq   #-128,Dx
  833.     |                                      subq.l  #n+128,Dx
  834.     |
  835.     | Where -136<=n<=-129. Not for 68040.
  836.     +------------------------------------------------------------------
  837.     |      move.l  #n,Dx           =>      moveq   #m,Dx
  838.     |                                      not.b   Dx
  839.     |
  840.     | Where n=255-m (128>m>=0). Not for 68040.
  841.     +------------------------------------------------------------------
  842.     |      move.l  #n,Dx           =>      moveq   #m,Dx
  843.     |                                      not.w   Dx
  844.     |
  845.     | Where 65534 <= n <= 65408 , m = 65535-n. Not for 68040.
  846.     +------------------------------------------------------------------
  847.     |      move.l  #n,Dx           =>      moveq   #m,Dx
  848.     |                                      not.w   Dx
  849.     |
  850.     | Where -65409 <= n <= -65536, m = 65535+n. Not for 68040.
  851.     +------------------------------------------------------------------
  852.     |      move.l  #n,Dx           =>      moveq   #m,Dx
  853.     |                                      swap    Dx
  854.     |
  855.     | Where n=m*65536 (-128<=m<=127). Not for 68040.
  856.     +------------------------------------------------------------------
  857.     |      Other moves are very complicated and not implemented.
  858.     |      Those uses thing like
  859.     |              move.l  #n,dx   =>      moveq   #m,dx
  860.     |                                      bchg    dx,dx
  861.     |      or
  862.     |                              =>      moveq   #m,dx
  863.     |                                      lsl.l   #p,dx
  864.     |      I think they are not worth.
  865.     +------------------------------------------------------------------
  866.     |      mul optim - separate module mulopt.c ...
  867.     |      UNSAFE...
  868.     +------------------------------------------------------------------
  869.     |      neg.x   Rx              =>      <deleted>
  870.     |      sub.x   Rx,Ry                   add.x   Rx,Ry
  871.     |
  872.     | add or sub. Where Rx is dead
  873.     +------------------------------------------------------------------
  874.     |      or.l #n,dx                      => bset.l #b,dx
  875.     |
  876.     | Where n = 2^b (only 1 bit on). Not for 68020+.
  877.     +------------------------------------------------------------------
  878.  
  879. **** WHAT IS DONE IN mc40opt.c:
  880.  
  881.     +------------------------------------------------------------------
  882.     |      ext.w   Dn              =>      extb.l  Dn
  883.     |      ext.l   Dn                      <deleted>
  884.     |
  885.     | Only if newinsts is set.
  886.     +------------------------------------------------------------------
  887.     |      sub.l   Ax,Ax           =>      lea     0.W,Ax
  888.     +------------------------------------------------------------------
  889.     |      swap    dx              =>      and.l   #65535,dx
  890.     |      clr.w   dx                      <deleted>
  891.     |      swap    dx                      <deleted>
  892.     +------------------------------------------------------------------
  893.     |      asl.l   #N,Dn           =>      <deleted>
  894.     |      ...(1)                          ...(1)
  895.     |      INST    ..(Ap,Dn.L)..           INST    ..(Ap,Dn.L*M)..
  896.     |
  897.     | M = 2^N.
  898.     | Where (1) does not use Dn and Dn is dead after last instruction.
  899.     +------------------------------------------------------------------
  900.     |      lea     n(Ax),Ax        =>      adda.w  #n,Ax
  901.     +------------------------------------------------------------------
  902.     |      lea     0(Am,Rn.l),Ao   =>      move.l  Am, Ao
  903.     |                                      add.l   Rn, Ao
  904.     +------------------------------------------------------------------
  905.     |      INST    0(Am,Rn.l),X    =>      add.l   Rn,Am
  906.     |                                      INST    (Am),X
  907.     |
  908.     | Where Am is dead. X must not refer Am.
  909.     +------------------------------------------------------------------
  910.     |      INST    X,0(Am,Rn.l)    =>      add.l   Rn,Am
  911.     |                                      INST    X,(Am)
  912.     |
  913.     | Where Am is dead. X must not refer Am.
  914.     +------------------------------------------------------------------
  915.     |      lea     N(Am,Rn.l),Ao   =>      LEA     N(Am),Ao
  916.     |                                      add.l   Rn,Ao
  917.     +------------------------------------------------------------------
  918.     |      bclr.l  #b,dx           =>      and.l   #n,dx
  919.     |
  920.     | n = ~(1<<b) (not for size opt.)
  921.     +------------------------------------------------------------------
  922.     |      st      X               =>      move.b  #-1,X
  923.     +------------------------------------------------------------------
  924.     |      move.l  #X,dx           =>      move.l  #Y,dx
  925.     |      ARITM   #n,dx                   <deleted>
  926.     |
  927.     | Compute Y correctly.
  928.     +------------------------------------------------------------------
  929.     |      move.l  #X,dx           =>      move.l  #Y,dx
  930.     |      swap    dx                      <deleted>
  931.     |
  932.     | Compute Y correctly.
  933.     +------------------------------------------------------------------
  934.     |      move[q].l #X,dx         =>      move.l  #Y,dx
  935.     |      not.x     dx                    <deleted>
  936.     |
  937.     | Compute Y correctly.
  938.     +------------------------------------------------------------------
  939.     |      bset.l  #b,dx           =>      or.l    #n,dx
  940.     |
  941.     | n = (1<<b)
  942.     +------------------------------------------------------------------
  943.     |      pea     (Ax)            =>      move.l  Ax,-(sp)
  944.     +------------------------------------------------------------------
  945.     |      move.l  #n,Dx           =>      <deleted>
  946.     |      INST.x  Dx,Rn                   INST.x  #n,Rn
  947.     |
  948.     | Where Dx is dead.
  949.     | x = .w or .l. INST = cmp|and|or|sub|add|eor.
  950.     +------------------------------------------------------------------
  951.     |      sub.l   #n,Ax           =>      add.l   #-n,Ax
  952.     +------------------------------------------------------------------
  953.     |      INST1   <mem>           =>      INST1   <mem>
  954.     |      INST2   <mem>                   INST3   <reg | imm>
  955.     |      INST3   <reg | imm>             INST2   <mem>
  956.     |
  957.     | Where INST1 and INST2 references memory and INST3 is only using
  958.     | regs or immediate data. Regs sets by INST3 must not be used by
  959.     | INST2. Regs sets by INST2 must not be used by INST3.
  960.     | UNSAFE: INST2 might set regs that are also set by INST3.
  961.     +------------------------------------------------------------------
  962.     |      link    An,#0           =>      move.l  An,-(sp)
  963.     |                                      move.l  SP,An
  964.     +------------------------------------------------------------------
  965.     |      move    #n,Dy           =>      <deleted>
  966.     |      cmp.x   Dx,Dy                   cmp.x   #n,Dx
  967.     |      b<cc>   lbl                     b<cci>  lbl
  968.     |
  969.     | Where Dy is dead. b<cci> is the inverse branch.
  970.     +------------------------------------------------------------------
  971.     |      asl.x   #n,X            =>      lsl.x   #n,X
  972.     +------------------------------------------------------------------
  973.     |      INST (An)+,X            =>      INST (An),X
  974.     |
  975.     | Where An is dead.
  976.     +------------------------------------------------------------------
  977.     |      INST X,(An)+            =>      INST X,(An)
  978.     |
  979.     | Where An is dead.
  980.     +------------------------------------------------------------------
  981.     |      rts                     =>      move.l  (sp)+,An
  982.     |                                      jmp     (An)
  983.     |
  984.     | Where An is dead.
  985.     +------------------------------------------------------------------
  986.  
  987. **** WHAT IS DONE IN mc20opt.c:
  988.  
  989.     +------------------------------------------------------------------
  990.     |      ext.w   Dn              =>      extb.l  Dn
  991.     |      ext.l   Dn                      <deleted>
  992.     |
  993.     | Only if newinsts is set.
  994.     +------------------------------------------------------------------
  995.     |      add.w   #n,Ax           =>      add.l   #n,Ax
  996.     |
  997.     | Add or sub.
  998.     +------------------------------------------------------------------
  999.     |      link    An,#0           =>      move.l  An,-(sp)
  1000.     |                                      move.l  SP,An
  1001.     +------------------------------------------------------------------
  1002.     |      swap    dx              =>      and.l   #65535,dx
  1003.     |      clr.w   dx                      <deleted>
  1004.     |      swap    dx                      <deleted>
  1005.     +------------------------------------------------------------------
  1006.     |      asl.l   #N,Dn           =>      <deleted>
  1007.     |      ...(1)                          ...(1)
  1008.     |      INST    ..(Ap,Dn.L)..           INST    ..(Ap,Dn.L*M)..
  1009.     |
  1010.     | M = 2^N.
  1011.     | Where (1) does not use Dn and Dn is dead after last instruction.
  1012.     +------------------------------------------------------------------
  1013.     |      lea     0(Am,Rn.l),Ao   =>      move.l  Am, Ao
  1014.     |                                      add.l   Rn, Ao
  1015.     +------------------------------------------------------------------
  1016.     |      INST    0(Am,Rn.l),X    =>      add.l   Rn,Am
  1017.     |                                      INST    (Am),X
  1018.     |
  1019.     | Where Am is dead. X must not refer Am.
  1020.     +------------------------------------------------------------------
  1021.     |      INST    X,0(Am,Rn.l)    =>      add.l   Rn,Am
  1022.     |                                      INST    X,(Am)
  1023.     |
  1024.     | Where Am is dead. X must not refer Am.
  1025.     +------------------------------------------------------------------
  1026.     |      lea     N(Am,Rn.l),Ao   =>      LEA     N(Am),Ao
  1027.     |                                      add.l   Rn,Ao
  1028.     +------------------------------------------------------------------
  1029.     |      bclr.l  #b,dx           =>      and.l   #n,dx
  1030.     |
  1031.     | n = ~(1<<b) (not for size optimisations).
  1032.     +------------------------------------------------------------------
  1033.     |      move.l  #X,dx           =>      move.l  #Y,dx
  1034.     |      ARITM   #n,dx                   <deleted>
  1035.     |
  1036.     | Compute Y correctly.
  1037.     +------------------------------------------------------------------
  1038.     |      move.l  #X,dx           =>      move.l  #Y,dx
  1039.     |      swap    dx                      <deleted>
  1040.     |
  1041.     | Compute Y correctly.
  1042.     +------------------------------------------------------------------
  1043.     |      move.l  #X,dx           =>      move.l  #Y,dx
  1044.     |      not.x   dx                      <deleted>
  1045.     |
  1046.     | Compute Y correctly.
  1047.     +------------------------------------------------------------------
  1048.     |      bset.l  #b,dx           =>      or.l    #n,dx
  1049.     |
  1050.     | n = (1<<b) (not for size opt.)
  1051.     +------------------------------------------------------------------
  1052.     |      move.l  Ax,Dy           =>      add.l   Ax,Ax
  1053.     |      lsl.l   #3,Dy                   add.l   Ax,Ax
  1054.     |      move.l  Dy,Ax                   add.l   Ax,Ax
  1055.     |
  1056.     | Where Dy is dead. UNSAFE: lsl sets the flags. add does'nt.
  1057.     +------------------------------------------------------------------
  1058.     |      INST1   <mem write>     =>      INST1   <mem write>
  1059.     |      INST2   <mem>                   INST3   <reg | imm>
  1060.     |      INST3   <reg | imm>             INST2   <mem>
  1061.     |
  1062.     | Where INST1 write to memory, INST2 references memory for
  1063.     | reading or writing and INST3 is only using regs or immediate
  1064.     | data. Regs sets by INST3 must not be used by INST2. Regs sets
  1065.     | by INST2 must not be used by INST3.
  1066.     | UNSAFE: INST2 might set regs that are also set by INST3.
  1067.     +------------------------------------------------------------------
  1068.  
  1069. **** WHAT IS DONE IN ulink.c:
  1070.  
  1071.     +------------------------------------------------------------------
  1072.     |      _LABEL1 ...             =>      _LABEL1 ...
  1073.     |              link    Am,X                    <deleted>
  1074.     |              ...                             ...
  1075.     |              <stuff>                         <stuff>
  1076.     |              ...                             ...
  1077.     |              unlink  Am                      <deleted>
  1078.     |              ...                             ...
  1079.     |      _LABEL2 ...                     _LABEL2 ...
  1080.     |
  1081.     | Where Am is not used in <stuff>.
  1082.     +------------------------------------------------------------------
  1083.  
  1084. **** WHAT IS DONE IN branchopt.c:
  1085.  
  1086.     +------------------------------------------------------------------
  1087.     |              ...                             ..__    
  1088.     |              b<cc>   lbl2    =>              b<cc>   lbl1
  1089.     |              bra     lbl1                    <deleted>
  1090.     |      lbl2    ...                     lbl2    ...
  1091.     +------------------------------------------------------------------
  1092.     |              ...                             ..__    
  1093.     |              bra     lbl1    =>              b<cc>   lbl3
  1094.     |      lbl2    ...                     lbl2    ...
  1095.     |              ...                             ...
  1096.     |      lbl1    b<cc>   lbl2            lbl1    b<cc>   lbl2
  1097.     |              ...                     lbl3    ...
  1098.     +------------------------------------------------------------------
  1099.     |
  1100.     |              move.y  #n,Rn   =>              move.y  #n,Rn
  1101.     |              ...(1)                          ...(1)
  1102.     |              bra     lbl1                    bra     XXX
  1103.     |              ...(2)                          ...(2)
  1104.     |      lbl1    cmp.x   #m,Rn             lbl1  cmp.x   #m,Rn
  1105.     |              b<cc>   lbl2                    b<cc>   lbl2
  1106.     |              ...(3)                    lbl3  ...(3)
  1107.     |
  1108.     | Where Rn is not set in (1), y>=x. XXX is lbl3 if b<cc> is true
  1109.     | or lbl2 else.
  1110.     +------------------------------------------------------------------
  1111.     |              move.y  #n,Rn   =>              move.y  #n,Rn
  1112.     |              ...(1)                          ...(1)
  1113.     |              bra     lbl1                    bra     XXX
  1114.     |              ...(2)                          ...(2)
  1115.     |      lbl1    move    #m,Ry             lbl1  move    #m,Ry
  1116.     |              cmp.x   Rn,Ry                   cmp.x   Rn,Ry
  1117.     |              b<cc>   lbl2                    b<cc>   lbl2
  1118.     |              ...(3)                    lbl3  ...(3)
  1119.     |
  1120.     | Where Rn is not set in (1), y>=x. XXX is lbl3 if b<cc> is true
  1121.     | or lbl2 else. And where Ry is dead after the cmp.
  1122.     +------------------------------------------------------------------
  1123.     |              move.y  #n,Rn   =>              move.y  #n,Rn
  1124.     |              ...(1)                          ...(1)
  1125.     |              bra     lbl1                    bra     XXX
  1126.     |              ...(2)                          ...(2)
  1127.     |      lbl1    move    #m,Dy             lbl1  move    #m,Dy
  1128.     |              cmp.x   Dy,Rn                   cmp.x   Dy,Rn
  1129.     |              b<cc>   lbl2                    b<cc>   lbl2
  1130.     |              ...(3)                    lbl3  ...(3)
  1131.     |
  1132.     | Where Rn is not set in (1), y>=x. XXX is lbl3 if b<cc> is true
  1133.     | or lbl2 else. And Dy is dead after the cmp.
  1134.     +------------------------------------------------------------------
  1135.     |              move.y  #n,Rn   =>              move.y  #n,Rn
  1136.     |              ...(1)                          ...(1)
  1137.     |              bra     lbl1                    bra     XXX
  1138.     |              ...(2)                          ...(2)
  1139.     |      lbl1    tst.x   Rn                lbl1  tst.x   Rn
  1140.     |              b<cc>   lbl2                    b<cc>   lbl2
  1141.     |              ...(3)                    lbl3  ...(3)
  1142.     |
  1143.     | Where Rn is not set in (1), y>=x. XXX is lbl3 if b<cc> is true 
  1144.     | or lbl2 else.
  1145.     +------------------------------------------------------------------
  1146.  
  1147. **** WHAT IS DONE IN branchopt2.c:
  1148.  
  1149.     +------------------------------------------------------------------
  1150.     |      Delete code never reached: Such a code is a
  1151.     |      code following an inconditionnal jump that
  1152.     |      bears no label. This is not true for a series
  1153.     |      of      jmp     lbl1(pc)
  1154.     |              jmp     lbl2(pc)
  1155.     |      that is used for jump tables.
  1156.     +------------------------------------------------------------------
  1157.  
  1158. **** WHAT IS DONE IN jsropt.c:
  1159.  
  1160.     +------------------------------------------------------------------
  1161.     |      jsr     LBL(pc)         =>      bsr     LBL
  1162.     +------------------------------------------------------------------
  1163.     |      jmp     LBL(pc)         =>      bra     LBL
  1164.     |
  1165.     | Not for jump tables. (bra might become bra.s, thus reduction of
  1166.     | 2 bytes, thus mismatching address (jmp LBL(pc) takes always 4 
  1167.     | bytes)).
  1168.     +------------------------------------------------------------------
  1169.     |      jsr     XXX             =>      jmp     XXX
  1170.     |      rts                             <deleted>
  1171.     |
  1172.     | The rts line must not bear a label.
  1173.     +------------------------------------------------------------------
  1174.     |      bsr     XXX             =>      bra     XXX
  1175.     |      rts                             <deleted>
  1176.     |
  1177.     | The rts line must not bear a label.
  1178.     +------------------------------------------------------------------
  1179.     |      bsr     lbl1            =>      pea     lbl2
  1180.     |      bra     lbl2                    bra     lbl1
  1181.     |      
  1182.     | Inst jsr or bsr. bra or jmp. We need not test is bra bears
  1183.     | a label since braopt has been performed before. 
  1184.     | Not for 68020/30.
  1185.     +------------------------------------------------------------------
  1186.  
  1187. **** WHAT IS DONE IN movem.c:
  1188.  
  1189.     +------------------------------------------------------------------
  1190.     |      _LABEL1 ...             =>      _LABEL1 ...
  1191.     |              movem.x MSK,-(sp)               movem.x MSK2,-(sp)
  1192.     |              ...                             sub     #N,sp
  1193.     |              ...                             ...
  1194.     |              ...                             ...
  1195.     |              ...                             add     #N,sp
  1196.     |              movem.x (sp)+,MSK               movem.x (sp)+,MSK2
  1197.     |              ...                             ...
  1198.     |      _LABEL2 ...                     _LABEL2 ...
  1199.     |
  1200.     | MSK2 is MSK without unused regs between the two labels.
  1201.     | Delete or replace movem by move if needed. N is used to
  1202.     | fix stack offset. On a 68000 this doesn't improve speed if
  1203.     | x=.w and difference between MSK and MSK2 is less than two bits.
  1204.     |
  1205.     | Note: substituting M(SP) by M-N(SP) between the labels is 
  1206.     | too unsafe.
  1207.     +------------------------------------------------------------------
  1208.     | movem40src(): movem MSK,-(Ax) => multiples moves. 
  1209.     | return next inst. (Opt. suggested by P.Lauly)
  1210.     +------------------------------------------------------------------
  1211.     | movem40dst() : movem (Ax)+,MSK => multiples moves. 
  1212.     | return next inst. (Opt. suggested by P.Lauly)
  1213.     +------------------------------------------------------------------
  1214.     | movem20src() : movem MSK,-(Ax) => multiples moves 
  1215.     | (if <= 2 regs). return next inst. (Opt. suggested 
  1216.     | by L.Marechal)
  1217.     +------------------------------------------------------------------
  1218.     | movem20dst() : movem (Ax)+,MSK => multiples moves 
  1219.     | (if <= 10 regs). return next inst. (Opt. suggested 
  1220.     | by L.Marechal)
  1221.     +------------------------------------------------------------------
  1222.     | movem00src() : movem MSK,-(Ax) => multiples moves 
  1223.     | (if <= 2 regs).
  1224.     +------------------------------------------------------------------
  1225.     | movem00dst() : movem (Ax)+,MSK => multiples moves 
  1226.     | (if <= 3 regs).
  1227.     +------------------------------------------------------------------
  1228.  
  1229. **** WHAT IS DONE IN stackopt.c:
  1230.  
  1231.     +------------------------------------------------------------------
  1232.     |      stackopt() - Tries to merge multiples add #n,sp together.
  1233.     +------------------------------------------------------------------
  1234.